//Wrapper for EE::Material
#pragma once
#include "stdafx.h"

namespace EsenthelNet
{
	///<summary>Material Techniques</summary>
	public enum class MaterialTechnique {
		///<summary>Default</summary>
		MTECH_DEFAULT   , 
		///<summary>Alpha provided in the textures will be used as transparency subtracted by 'color.alpha' used in alpha testing</summary>
		MTECH_ALPHA_TEST,
		///<summary>Render as fur effect, where 'det_scale'=fur intensity, 'det_power'=fur length</summary>
		MTECH_FUR       ,
		///<summary>Render as grass, which will make mesh vertexes bend on the wind, bending intensity is taken from source vertex Y position, which should be in the range from 0 to 1</summary>
		MTECH_GRASS     , 
		///<summary>Render as leafs, which will make mesh vertexes bend on the wind, MeshBase::vtx.hlp must be set to indicate leaf attachment position to its branch, if MeshBase::vtx.size is set it will be used as leaf uniqe bending angle offset</summary>
		MTECH_LEAF      , 
		///<summary>Mesh will be smoothly blended on the screen using alpha values</summary>
		MTECH_BLEND    
	};

	///<summary>Mesh Rendering Material - contains render parameters and textures</summary>
	public ref class Material {
	internal:
		Material(EE::Material m) {
			mat = new EE::Material();
			*mat = m;
		}
		Material(EE::Material* m) {
			mat = m;
		}
		EE::Material* mat;
	public:
		Material() {
			mat = new EE::Material();
		}
		~Material() { delete mat; }

		///<summary>Ambient (0,0,0)..(1,1,1), default=(0,0,0)</summary>
		PropVec(Ambient, mat->ambient)
		///<summary>Specular 0..1, default=0</summary>
		Prop(float, Specular, mat->specular)
		///<summary>Sub-surface scattering 0..1, default=0</summary>
		Prop(float, SubSurfaceScattering, mat->sss)
		///<summary>Glow amount 0..1, default=0</summary>
		Prop(float, Glow, mat->glow)
		///<summary>Roughness 0..1, default=0.5</summary>
		Prop(float, Rough, mat->rough)
		///<summary>Bumpiness 0..0.09, default=0.03</summary>
		Prop(float, Bump, mat->bump)
		///<summary>Texture coordinates scale 0..Inf, default=1, this is used mainly for World Editor terrain textures scaling, not supported on Shader Model 2.0</summary>
		Prop(float, TexScale, mat->tex_scale)
		///<summary>Detail coordinates scale 0 .. Inf, default=4</summary>
		Prop(float, DetScale, mat->det_scale)
		///<summary>Detail power 0..1, default=0.3</summary>
		Prop(float, DetPower, mat->det_power)
		///<summary>Reflect 0..1, default=0.2</summary>
		Prop(float, Reflect, mat->reflect)

		///<summary>If face culling enabled, default=true</summary>
		Prop(bool, Cull, mat->cull)
		///<summary>Material technique, default=MTECH_DEFAULT</summary>
		PropTarget(EsenthelNet::MaterialTechnique, Technique, mat->technique, EE::MATERIAL_TECHNIQUE)

		///<summary>Diffuse texture (color), default=NULL</summary>
		PropImage(Diffuse, mat->diffuse)
		///<summary>Normal texture, default=NULL</summary>
		PropImage(Normal, mat->normal)
		///<summary>Detail texture, default=NULL</summary>
		PropImage(Detail, mat->detail)
		///<summary>Macro texture, default=NULL</summary>
		PropImage(Macro, mat->macro)
		///<summary>Reflection texture, default=NULL</summary>
		PropImage(Reflection, mat->reflection)
		///<summary>LightMap texture, default=NULL</summary>
		PropImage(LightMap, mat->light_map)


		///<summary>Reset to default values</summary>
		void Reset() { mat->reset(); }
		///<summary>This needs to be called after manually changing the parameters/textures</summary>
		void Validate() { mat->validate(); }

		///<summary>Save binary, false on fail</summary>
		bool Save(System::String^ name) { return mat->save(ToEEStr(name)); }
		///<summary>Load binary, false on fail</summary>
		bool Load(System::String^ name) { return mat->load(ToEEStr(name)); }
		///<summary>Save text, false on fail</summary>
		bool SaveTxt(System::String^ name) { return mat->saveTxt(ToEEStr(name)); }
		///<summary>Load text, false on fail</summary>
		bool LoadTxt(System::String^ name) { return mat->loadTxt(ToEEStr(name)); }


		///<summary>Gets a Material from the Cache.</summary>
		static EsenthelNet::Material^ Cache(System::String^ s) {
			return gcnew EsenthelNet::Material(*EE::Materials(ToEEStr(s)));
		}

	};

}

#define PropMaterial(name, var) property EsenthelNet::Material^ name { EsenthelNet::Material^ get() { return gcnew EsenthelNet::Material(var); } void set(EsenthelNet::Material^ img) { var = img->mat; }}